package cn.geminis.lowcode.compiler.code;

import cn.geminis.lowcode.compiler.Context;
import cn.geminis.lowcode.compiler.util.JdkTreeMakerUtils;
import cn.geminis.lowcode.compiler.util.JdkCompilerClass;
import cn.geminis.lowcode.utils.Utils;
import com.sun.source.tree.PackageTree;

import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import java.util.Objects;

/**
 * @author puddi
 */
public class LcPackage extends AbstractCode<PackageTree, PackageElement> {

    public static LcPackage ensure(String name) {
        var element = Context.INSTANCE.getElementUtils().getPackageElement(name);
        if (Objects.isNull(element)) {
            return new LcPackage(name);
        } else {
            return new LcPackage(element);
        }
    }

    private String name;

    public LcPackage(Element element) {
        super(element);
    }

    private LcPackage(String name) {
        this.name = name;
    }

    @Override
    protected PackageTree createJdkTree() {
        return JdkTreeMakerUtils.packageDef(name);
    }

    @Override
    protected PackageElement createJdkElement() {
        var element = (PackageElement) Utils.callConstructor(
                JdkCompilerClass.PACKAGE_SYMBOL,
                new Class[]{
                        JdkCompilerClass.NAME,
                        JdkCompilerClass.SYMBOL
                },
                Context.INSTANCE.getElementUtils().getName(name),
                null
        );
        Utils.setField(
                element,
                "members_field",
                Utils.callMethodWithTypes(
                        JdkCompilerClass.WRITEABLE_SCOPE,
                        "create",
                        new Class[]{
                                JdkCompilerClass.SYMBOL
                        },
                        element
                )
        );

        return element;
    }
}
